﻿using System;
using System.Diagnostics;
using System.Net;
using HslCommunication.BasicFramework;
using HslCommunication.Core.Net;
using HslCommunication.LogNet;
using HslCommunication.Reflection;

namespace HslCommunication.Robot.Hyundai
{
	/// <summary>
	/// 现代机器人的UDP通讯类，注意本类是服务器，需要等待机器人先配置好ip地址及端口，然后连接到本服务器才能正确的进行操作。详细参见api文档注释<br />
	/// The UDP communication class of modern robots. Note that this class is a server. You need to wait for the robot to configure the IP address and port first, 
	/// and then connect to this server to operate correctly. See api documentation for details
	/// </summary>
	/// <remarks>
	/// 为使用联机跟踪功能，通过JOB文件的 OnLTrack 命令激活本功能后对通信及位置增量命令 Filter 进行设置，必要时以 LIMIT 命令设置机器人的动作领域，速度限制项。
	/// 最后采用 OnLTrack 命令关闭联机跟踪功能以退出本功能。<br />
	/// 功能开始，通信及 Filter 设置，程序示例： OnLTrack ON,IP=192.168.1.254,PORT=7127,CRD=1,Bypass,Fn=10
	/// </remarks>
	// Token: 0x02000031 RID: 49
	public class HyundaiUdpNet : NetworkUdpServerBase
	{
		/// <summary>
		/// 实例化一个默认的对象<br />
		/// Instantiate a default object
		/// </summary>
		// Token: 0x0600038E RID: 910 RVA: 0x0000E598 File Offset: 0x0000C798
		public HyundaiUdpNet()
		{
			this.incrementCount = new SoftIncrementCount(2147483647L, 0L, 1);
		}

		/// <inheritdoc />
		// Token: 0x0600038F RID: 911 RVA: 0x0000E5B8 File Offset: 0x0000C7B8
		protected override void ThreadReceiveCycle()
		{
			while (base.IsStarted)
			{
				IPEndPoint remote = new IPEndPoint(IPAddress.Any, 0);
				this.Remote = remote;
				byte[] array = new byte[64];
				int num;
				try
				{
					num = this.CoreSocket.ReceiveFrom(array, ref this.Remote);
				}
				catch (Exception ex)
				{
					bool isStarted = base.IsStarted;
					if (isStarted)
					{
						ILogNet logNet = base.LogNet;
						if (logNet != null)
						{
							logNet.WriteException("ThreadReceiveCycle", ex);
						}
					}
					continue;
				}
				bool flag = num != 64;
				if (flag)
				{
					ILogNet logNet2 = base.LogNet;
					if (logNet2 != null)
					{
						logNet2.WriteError(this.ToString(), string.Format("Receive Error Length[{0}]: {1}", num, array.ToHexString()));
					}
				}
				else
				{
					ILogNet logNet3 = base.LogNet;
					if (logNet3 != null)
					{
						logNet3.WriteDebug(this.ToString(), "Receive: " + array.ToHexString());
					}
					HyundaiData hyundaiData = new HyundaiData(array);
					bool flag2 = hyundaiData.Command == 'S';
					if (flag2)
					{
						this.Write(new HyundaiData(array)
						{
							Command = 'S',
							Count = 0,
							State = 1
						});
						ILogNet logNet4 = base.LogNet;
						if (logNet4 != null)
						{
							logNet4.WriteDebug(this.ToString(), "Send: " + hyundaiData.ToBytes().ToHexString());
						}
						ILogNet logNet5 = base.LogNet;
						if (logNet5 != null)
						{
							logNet5.WriteDebug(this.ToString(), "Online tracking is started by Hi5 controller.");
						}
					}
					else
					{
						bool flag3 = hyundaiData.Command == 'P';
						if (flag3)
						{
							this.hyundaiDataHistory = hyundaiData;
							HyundaiUdpNet.OnHyundaiMessageReceiveDelegate onHyundaiMessageReceive = this.OnHyundaiMessageReceive;
							if (onHyundaiMessageReceive != null)
							{
								onHyundaiMessageReceive(hyundaiData);
							}
						}
						else
						{
							bool flag4 = hyundaiData.Command == 'F';
							if (flag4)
							{
								ILogNet logNet6 = base.LogNet;
								if (logNet6 != null)
								{
									logNet6.WriteDebug(this.ToString(), "Online tracking is finished by Hi5 controller.");
								}
							}
						}
					}
				}
			}
		}

		/// <summary>
		/// 将指定的增量写入机器人，需要指定6个参数，位置和角度信息，其中位置单位为mm，角度单位为°<br />
		/// To write the specified increment to the robot, you need to specify 6 parameters, 
		/// position and angle information, where the position unit is mm and the angle unit is °
		/// </summary>
		/// <param name="x">X轴增量信息，单位毫米</param>
		/// <param name="y">Y轴增量信息，单位毫米</param>
		/// <param name="z">Z轴增量信息，单位毫米</param>
		/// <param name="rx">X轴角度增量信息，单位角度</param>
		/// <param name="ry">Y轴角度增量信息，单位角度</param>
		/// <param name="rz">Z轴角度增量信息，单位角度</param>
		/// <returns>是否写入机器人成功</returns>
		// Token: 0x06000390 RID: 912 RVA: 0x0000E7A8 File Offset: 0x0000C9A8
		[HslMqttApi]
		public OperateResult WriteIncrementPos(double x, double y, double z, double rx, double ry, double rz)
		{
			return this.WriteIncrementPos(new double[]
			{
				x,
				y,
				z,
				rx,
				ry,
				rz
			});
		}

		/// <summary>
		/// 将指定的增量写入机器人，需要指定6个参数，位置和角度信息，其中位置单位为mm，角度单位为°<br />
		/// To write the specified increment to the robot, you need to specify 6 parameters, position and angle information, where the position unit is mm and the angle unit is °
		/// </summary>
		/// <param name="pos">增量的数组信息</param>
		/// <returns>是否写入机器人成功</returns>
		// Token: 0x06000391 RID: 913 RVA: 0x0000E7E4 File Offset: 0x0000C9E4
		[HslMqttApi]
		public OperateResult WriteIncrementPos(double[] pos)
		{
			HyundaiData hyundaiData = new HyundaiData
			{
				Command = 'P',
				State = 2,
				Count = (int)this.incrementCount.GetCurrentValue()
			};
			for (int i = 0; i < hyundaiData.Data.Length; i++)
			{
				hyundaiData.Data[i] = pos[i];
			}
			return this.Write(hyundaiData);
		}

		/// <summary>
		/// 将指定的命令写入机器人，该命令是完全自定义的，需要遵循机器人的通讯协议，在写入之前，需要调用<see cref="M:HslCommunication.Core.Net.NetworkUdpServerBase.ServerStart(System.Int32)" /> 方法<br />
		/// Write the specified command to the robot. The command is completely customized and needs to follow the robot's communication protocol. 
		/// Before writing, you need to call the <see cref="M:HslCommunication.Core.Net.NetworkUdpServerBase.ServerStart(System.Int32)" />
		/// </summary>
		/// <param name="data">机器人数据</param>
		/// <returns>是否写入成功</returns>
		// Token: 0x06000392 RID: 914 RVA: 0x0000E84C File Offset: 0x0000CA4C
		[HslMqttApi]
		public OperateResult Write(HyundaiData data)
		{
			bool flag = !base.IsStarted;
			OperateResult result;
			if (flag)
			{
				result = new OperateResult("Please Start Server First!");
			}
			else
			{
				bool flag2 = this.Remote == null;
				if (flag2)
				{
					result = new OperateResult("Please Wait Robot Connect!");
				}
				else
				{
					try
					{
						this.CoreSocket.SendTo(data.ToBytes(), this.Remote);
						result = OperateResult.CreateSuccessResult();
					}
					catch (Exception ex)
					{
						result = new OperateResult(ex.Message);
					}
				}
			}
			return result;
		}

		/// <summary>
		/// 机器人在X轴上移动一小段距离，单位毫米<br />
		/// The robot moves a short distance on the X axis, in millimeters
		/// </summary>
		/// <param name="value">移动距离，单位毫米</param>
		/// <returns>是否写入成功</returns>
		// Token: 0x06000393 RID: 915 RVA: 0x0000E8D4 File Offset: 0x0000CAD4
		[HslMqttApi]
		public OperateResult MoveX(double value)
		{
			return this.WriteIncrementPos(value, 0.0, 0.0, 0.0, 0.0, 0.0);
		}

		/// <summary>
		/// 机器人在Y轴上移动一小段距离，单位毫米<br />
		/// The robot moves a short distance on the Y axis, in millimeters
		/// </summary>
		/// <param name="value">移动距离，单位毫米</param>
		/// <returns>是否写入成功</returns>
		// Token: 0x06000394 RID: 916 RVA: 0x0000E90A File Offset: 0x0000CB0A
		[HslMqttApi]
		public OperateResult MoveY(double value)
		{
			return this.WriteIncrementPos(0.0, value, 0.0, 0.0, 0.0, 0.0);
		}

		/// <summary>
		/// 机器人在Z轴上移动一小段距离，单位毫米<br />
		/// The robot moves a short distance on the Z axis, in millimeters
		/// </summary>
		/// <param name="value">移动距离，单位毫米</param>
		/// <returns>是否写入成功</returns>
		// Token: 0x06000395 RID: 917 RVA: 0x0000E940 File Offset: 0x0000CB40
		[HslMqttApi]
		public OperateResult MoveZ(double value)
		{
			return this.WriteIncrementPos(0.0, 0.0, value, 0.0, 0.0, 0.0);
		}

		/// <summary>
		/// 机器人在X轴方向上旋转指定角度，单位角度<br />
		/// The robot rotates the specified angle in the X axis direction, the unit angle
		/// </summary>
		/// <param name="value">旋转角度，单位角度</param>
		/// <returns>是否写入成功</returns>
		// Token: 0x06000396 RID: 918 RVA: 0x0000E976 File Offset: 0x0000CB76
		[HslMqttApi]
		public OperateResult RotateX(double value)
		{
			return this.WriteIncrementPos(0.0, 0.0, 0.0, value, 0.0, 0.0);
		}

		/// <summary>
		/// 机器人在Y轴方向上旋转指定角度，单位角度<br />
		/// The robot rotates the specified angle in the Y axis direction, the unit angle
		/// </summary>
		/// <param name="value">旋转角度，单位角度</param>
		/// <returns>是否写入成功</returns>
		// Token: 0x06000397 RID: 919 RVA: 0x0000E9AC File Offset: 0x0000CBAC
		[HslMqttApi]
		public OperateResult RotateY(double value)
		{
			return this.WriteIncrementPos(0.0, 0.0, 0.0, 0.0, value, 0.0);
		}

		/// <summary>
		/// 机器人在Z轴方向上旋转指定角度，单位角度<br />
		/// The robot rotates the specified angle in the Z axis direction, the unit angle
		/// </summary>
		/// <param name="value">旋转角度，单位角度</param>
		/// <returns>是否写入成功</returns>
		// Token: 0x06000398 RID: 920 RVA: 0x0000E9E2 File Offset: 0x0000CBE2
		[HslMqttApi]
		public OperateResult RotateZ(double value)
		{
			return this.WriteIncrementPos(0.0, 0.0, 0.0, 0.0, 0.0, value);
		}

		/// <summary>
		/// 当接收到机器人数据的时候触发的事件
		/// </summary>
		// Token: 0x14000007 RID: 7
		// (add) Token: 0x06000399 RID: 921 RVA: 0x0000EA18 File Offset: 0x0000CC18
		// (remove) Token: 0x0600039A RID: 922 RVA: 0x0000EA50 File Offset: 0x0000CC50
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		public event HyundaiUdpNet.OnHyundaiMessageReceiveDelegate OnHyundaiMessageReceive;

		/// <inheritdoc />
		// Token: 0x0600039B RID: 923 RVA: 0x0000EA85 File Offset: 0x0000CC85
		public override string ToString()
		{
			return string.Format("HyundaiUdpNet[{0}]", base.Port);
		}

		// Token: 0x040000ED RID: 237
		private HyundaiData hyundaiDataHistory;

		// Token: 0x040000EE RID: 238
		private SoftIncrementCount incrementCount;

		// Token: 0x040000EF RID: 239
		private EndPoint Remote;

		/// <summary>
		/// 收到机器人消息的事件委托
		/// </summary>
		/// <param name="data">机器人消息</param>
		// Token: 0x0200022A RID: 554
		// (Invoke) Token: 0x060022D3 RID: 8915
		public delegate void OnHyundaiMessageReceiveDelegate(HyundaiData data);
	}
}
